<?php

/**
 * 基于COOKIE的 Zend_Auth 存储
 * Author:xydream@gmail.com
 * QQ:9926282
 */
class Hm_Auth_Storage_Cookie implements Zend_Auth_Storage_Interface
{
    /**
     * @var string
     */
    protected $_basedir = '/';
    /**
     * @var string
     */
    protected $_cookieName;
    /**
     * @var string
     */
    protected $_lifeTime;
    /**
     * @var string
     */
    protected $_domain;
    /**
     * @var string
     */
    protected $_secret;
    /**
     * @var mixed
     */
    protected $_cached;

    /**
     * 构造函数
     *
     * @param unknown_type $cookieName
     * @param unknown_type $secret
     * @param unknown_type $lifetime
     * @param unknown_type $path
     * @param unknown_type $domain
     */
    public function __construct ($cookieName = null, $secret = null, $lifeTime = 0, $path = '/', $domain = null)
    {
        if (null !== $cookieName) {
            $this->setCookieName($cookieName);
        }
        if (null !== $secret) {
            $this->setSecret($secret);
        }
        //$this->setLifeTime(time()+60*60*24*3);
        if (0 !== $lifeTime) {
            $this->setLifeTime($lifeTime);
        }
        if (null !== $path) {
            $this->setBasedir($path);
        }
        if ('/' !== $domain) {
            $this->setDomain($domain);
        }
    }

    /**
     * 返回cookie的生命周期
     *
     * @return string
     */
    public function getLifeTime ()
    {
        return $this->_lifeTime;
    }

    /**
     * 设定cookie的生命周期
     *
     * @param string $basedir
     * @return Portal_Auth_Storage_Cookie
     */
    public function setLifeTime ($lifeTime)
    {
        $this->_lifeTime = $lifeTime;
        return $this;
    }

    /**
     * 返回cookie的存储路径
     *
     * @return string
     */
    public function getBasedir ()
    {
        return $this->_basedir;
    }

    /**
     * 设定cookie的存储路径
     *
     * @param string $basedir
     * @return Portal_Auth_Storage_Cookie
     */
    public function setBasedir ($basedir)
    {
        $this->_basedir = $basedir;
        return $this;
    }

    /**
     * 返回Cookie的名称
     *
     * @return string
     */
    public function getCookieName ()
    {
        return $this->_cookieName;
    }

    /**
     * 设定Cookie的名称
     *
     * @param string $cookieName
     * @return Portal_Auth_Storage_Cookie
     */
    public function setCookieName ($cookieName)
    {
        $this->_cookieName = $cookieName;
        return $this;
    }

    /**
     * 返回域
     *
     * @return string
     */
    public function getDomain ()
    {
        return $this->_domain;
    }

    /**
     * 设定域
     *
     * @param string $domain
     * @return Portal_Auth_Storage_Cookie
     */
    public function setDomain ($domain)
    {
        $this->_domain = $domain;
        return $this;
    }

    /**
     * 返回密匙
     *
     * @return string
     */
    public function getSecret ()
    {
        return $this->_secret;
    }

    /**
     * 设定密匙
     *
     * @param string $secret
     * @return Portal_Auth_Storage_Cookie
     */
    public function setSecret ($secret)
    {
        $this->_secret = $secret;
        return $this;
    }

    /**
     * 只有当存储为空时才返回true
     *
     * @throws Zend_Auth_Storage_Exception 如果不能确定是否为空时将抛出
     * @return boolean
     */
    public function isEmpty ()
    {
        return $this->read() == null;
    }

    /**
     * 返回内容
     *
     * Behavior is undefined when storage is empty.
     *
     * @throws Zend_Auth_Storage_Exception 如果读取不到内容时抛出
     * @return mixed
     */
    public function read ()
    {
        if (! $this->_cached) {
            if (array_key_exists($this->_cookieName, $_COOKIE)) {
                $value = $_COOKIE[$this->_cookieName];
                list($contents, $now, $checksum) = explode('|', $value);
                $contents=base64_decode($contents);
                if (md5($contents . $now . $this->_secret) == $checksum) {
                    $this->_cached =unserialize($contents);
                }
            }
        }
        return $this->_cached;
    }

    /**
     * 写入COOKIE
     *
     * @param  mixed $contents
     * @throws Zend_Auth_Storage_Exception
     * @return void
     */
    public function write ($contents,$lifeTime = 0)
    {
        $contents=serialize($contents);
        $lifeTime||$lifeTime = $this->getLifeTime();
        $this->_cached = $contents;
        $now = time();
        $checksum = md5($contents . $now . $this->_secret);
        $value = base64_encode($contents) . '|' . $now . '|' . $checksum;
        if (! setcookie($this->getCookieName(), $value, $lifeTime, $this->getBasedir(), $this->getDomain(), $_SERVER['SERVER_PORT'] == 443 ? 1 : 0)) {
            throw new Zend_Auth_Storage_Exception('Failed to set cookie');
        }
    }

    /**
     * 清除COOKIE
     *
     * @throws Zend_Auth_Storage_Exception
     * @return void
     */
    public function clear ()
    {
        if (! setcookie($this->getCookieName(), false, // clears the cookie
time()-3600, $this->getBasedir(), $this->getDomain(), $_SERVER['SERVER_PORT'] == 443 ? 1 : 0)) {
            throw new Zend_Auth_Storage_Exception('Failed to clear cookie');
        }
    }
}
